import path from 'path';
import fsPromise from 'fs-promise';
// @ts-ignore
import colors from 'colors-console';
import sleep from '../lib/sleep';
import RSATool from '../lib/RSATool';

let configInit = false;

const defaultBaseConfig = {
    'version': 'v2.9',
    'clientCORS': true,
    'clientServerPort': 3000,
    'manageServerPort': 3001,
    'wsServerPort': 3001,
    'clientBlackList': [],
    'manageWhiteList': [
        '::ffff:127.0.0.1'
    ],
    'wwwPath': 'www',
    'MapBox': {
        'access_token': 'pk.eyJ1Ijoic3ZjLW9rdGEtbWFwYm94LXN0YWZmLWFjY2VzcyIsImEiOiJjbG5sMnExa3kxNTJtMmtsODJld24yNGJlIn0.RQ4CHchAYPJQZSiUJ0O3VQ',
        'header': {
            'Referer': 'https://geojson.io/'
        }
    },
    'TianDiTu': {
        'tk': ''
    },
    'CacheSave': {
        // 缓存到文件
        'CacheSaveFile': true,
        // 缓存到数据库
        'CacheSaveDB': false
    },
    'userList': [
        {'userName': 'user_1', 'nickname': '访客', 'password': '123456', 'role': 'client'},
        {'userName': 'admin', 'nickname': '管理员', 'password': '123456', 'role': 'manage'}
    ],
    'publicDer': '',
    'privateDer': ''
};
const defaultServiceConfig = {};
const configTool = {
    appBasePath: '',
    wwwPath: '',
    baseConfig: defaultBaseConfig,
    serviceConfig: defaultServiceConfig,
    async editConfig(key: string, value: any) {
        await this.init();
        let result = false;
        if (typeof this.baseConfig[key] === typeof value) {
            this.baseConfig[key] = value;
            await fsPromise.writeJSON(path.join(this.appBasePath, '/conf/baseConfig.json'), this.baseConfig);
            result = true;
        }
        return result;
    },
    async init() {
        return new Promise(async (resolve, reject) => {
            if (!configInit) {
                configInit = true;

                // 是否处于开发环境
                let isDev = !__dirname.includes('snapshot');

                if (isDev) {
                    this.appBasePath = path.join(__dirname, '../../');
                } else {
                    this.appBasePath = path.dirname(process.execPath);
                }

                await fsPromise.ensureDir(path.join(this.appBasePath, '/conf'));
                await fsPromise.ensureDir(path.join(this.appBasePath, '/temp/fileOut'));
                await fsPromise.ensureDir(path.join(this.appBasePath, '/temp/fileDB'));
                await fsPromise.ensureDir(path.join(this.appBasePath, '/temp/logs/clientServer'));
                await fsPromise.ensureDir(path.join(this.appBasePath, '/temp/logs/manageServerPort'));
                await fsPromise.ensureDir(path.join(this.appBasePath, '/www'));

                let configFile = path.join(this.appBasePath, '/conf/baseConfig.json');
                let serviceFile = path.join(this.appBasePath, '/conf/serviceConfig.json');

                // 判断是否读取本地已有的配置文件
                await fsPromise.readJson(configFile).then((d: any) => {
                    if (d.version === defaultBaseConfig.version) {
                        this.baseConfig = d;
                    } else {
                        console.log(colors('red', '----|||配置文件版本过低，未生效！！请重置配置文件|||----'));
                        throw new Error('配置文件版本不匹配');
                    }
                }).catch(() => {
                    // 新生成一份配置文件
                    this.baseConfig = defaultBaseConfig;
                    const {privateDer, publicDer} = RSATool.createKey(2048);
                    this.baseConfig.privateDer = privateDer;
                    this.baseConfig.publicDer = publicDer;

                    fsPromise.writeJSON(configFile, this.baseConfig);
                });

                await fsPromise.readJson(serviceFile).then((d: any) => {
                    this.serviceConfig = d;
                }).catch(() => {
                    fsPromise.writeJSON(serviceFile, this.serviceConfig);
                });


                // 判断wwwPath是否是绝对路径
                if (path.isAbsolute(this.baseConfig.wwwPath)) {
                    this.wwwPath = path.join(this.baseConfig.wwwPath);
                } else {
                    this.wwwPath = path.join(this.appBasePath, this.baseConfig.wwwPath);
                }
            }

            while (!configInit) {
                await sleep(50);
            }
            resolve(true);
        });

    },
    preservableONDB() {
        return this.baseConfig.CacheSave.CacheSaveDB;
    },
    preservableONFile() {
        return this.baseConfig.CacheSave.CacheSaveFile;
    }
};


export default configTool;
